import 'package:dio/dio.dart';
import 'package:framelib/config/api_config.dart';
import 'base_api.dart';
import 'base_entity_factory.dart';
import 'baseentity.dart';
import 'dioutils.dart';

/**
 * request请求封装
 */
mixin RequestManager {

  static final String POST='POST';
  static final String GET='GET';
  static final String PUT='PUT';
  static final String DELETE='DELETE';

  Future<BaseEntity> _requestData<T>(String method,String url,
      {
        String baseUrl, Map<String,dynamic> params, bool isFormData:false,bool isList,CancelToken cancelToken,Map<String,dynamic> queryParameters,
        Options options,List<Map<String,dynamic>> headers,Function generateOBJ,bool isAuth:false,String contentType,
      }) {
    var BaseEntity= DioUtils.instance.setBaseUrl(baseUrl: baseUrl??ApiConfig.BASE_URL,).setHeaders(headers:headers).
    requestNetwork<T>(method, url,isList: isList??false, isFormData: isFormData??true, params: params, queryParameters:queryParameters,
        options: options, cancelToken: cancelToken,generateOBJ: generateOBJ,isAuth: isAuth,contentType: contentType);
    return BaseEntity;
  }

  /**
   * T ：继承自BaseEntity实体类
   * S ：继承自BaseEntityFactory工具类，将json统一转换成实体类
   */
  _checkGenerateOBJ<T,S extends BaseEntityFactory>(var data, S s){
    return s.generateOBJ<T>(data);
  }

  /**
   * post请求
   */
  Future<BaseEntity> postData<T,S extends BaseEntityFactory>(S entityFac,String url,
      {
        String baseUrl, dynamic params, bool isFormData:false,bool isList,bool isAuth:false,
        CancelToken cancelToken,Map<String,dynamic> queryParameters,String contentType,
        Options options,List<Map<String,dynamic>> headers
      }) {

    return _requestData<T>(RequestManager.POST,url,baseUrl: baseUrl,params: params,isFormData: isFormData,isList: isList,cancelToken: cancelToken,
        queryParameters: queryParameters,options: options,headers: headers,isAuth:isAuth,contentType: contentType,
        generateOBJ: (var data)=>_checkGenerateOBJ<T,S>(data,entityFac));
  }

  /**
   * get请求
   */
  Future<BaseEntity> getData<T,S extends BaseEntityFactory>(S entityFac,String url,
      {
        String baseUrl, dynamic params, bool isFormData:false,bool isList,CancelToken cancelToken,Map<String,dynamic> queryParameters,
        Options options,List<Map<String,dynamic>> headers,bool isAuth:false,String contentType,
      }) {

    return _requestData<T>(RequestManager.GET,url,baseUrl: baseUrl,params: params,isFormData: isFormData,isList: isList,cancelToken: cancelToken,
        queryParameters: queryParameters,options: options,headers: headers,isAuth:isAuth,contentType: contentType,
        generateOBJ: (var data)=>_checkGenerateOBJ<T,S>(data,entityFac));
  }

  /**
   * put请求
   */
  Future<BaseEntity> putData<T,S extends BaseEntityFactory>(S entityFac,String url,
      {
        String baseUrl, dynamic params, bool isFormData:false,bool isList,CancelToken cancelToken,Map<String,dynamic> queryParameters,
        Options options,List<Map<String,dynamic>> headers,bool isAuth:false,String contentType,
      }) {

    return _requestData<T>(RequestManager.PUT,url,baseUrl: baseUrl,params: params,isFormData: isFormData,isList: isList,cancelToken: cancelToken,
        queryParameters: queryParameters,options: options,headers: headers,isAuth:isAuth,contentType: contentType,
        generateOBJ: (var data)=>_checkGenerateOBJ<T,S>(data,entityFac));
  }

  /**
   * delete请求
   */
  Future<BaseEntity> deleteData<T,S extends BaseEntityFactory>(S entityFac,String url,
      {
        String baseUrl, dynamic params, bool isFormData:false,bool isList,CancelToken cancelToken,Map<String,dynamic> queryParameters,
        Options options,List<Map<String,dynamic>> headers,bool isAuth:false,String contentType,
      }) {

    return _requestData<T>(RequestManager.DELETE,url,baseUrl: baseUrl,params: params,isFormData: isFormData,isList: isList,cancelToken: cancelToken,
        queryParameters: queryParameters,options: options,headers: headers,isAuth:isAuth,contentType: contentType,
        generateOBJ: (var data)=>_checkGenerateOBJ<T,S>(data,entityFac));
  }

}
